#pragma once
#include<iostream>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <cstring>
#include<unistd.h>
#include<functional>
#include<vector>

#include"inet_addr.hpp"
#include"log.hpp"
#include"pthread_pool.hpp"

template<class T>
class Route{
    private:
        static void* SeendToAll(void* ptr){
            std::pair<Route*,std::string>* p=(std::pair<Route*,std::string>*)ptr;
            Route* route=p->first;
            int fd=route->_socketfd;
            for(auto& client_addr:route->_client_addr){
                sendto(fd,p->second.c_str(),p->second.size(),0,(struct sockaddr*)&client_addr.second,sizeof(client_addr.second));
            }
            delete p;
            return nullptr;
        }
        void run(){
            char buffer[1024];
            while(true){
                memset(buffer,0,sizeof(buffer));
                struct sockaddr_in clientaddr;
                socklen_t addrlen=sizeof(clientaddr);
                memset(&clientaddr,0,addrlen);
                ssize_t n=recvfrom(_socketfd,buffer,sizeof(buffer)-1,0,(struct sockaddr*)&clientaddr,&addrlen);
                if(n==-1){
                    LOG(ly::LogLevel::ERROR)<<"读取错误"<<'\n';
                    perror("recvfrom failed");
                    close(_socketfd);
                    return;
                }
                else{
                    InetAddr client_addr(clientaddr);
                    LOG(ly::LogLevel::INFO)<<"接收到消息: "<<buffer<<" 来自 "<<client_addr.PrintDebug()<<'\n';
                    _client_addr[client_addr.PrintDebug()]=clientaddr;
                    _pool->push(SeendToAll,new std::pair<Route*,std::string>(this,std::string(buffer)));
                }
            }
        }
        // void Listen(int socketfd,int num){
        //     int n=listen(socketfd,num);
        //     std::cout<<socketfd<<std::endl;
        //     if(n==-1){
        //         LOG(ly::LogLevel::ERROR)<<"listen失败"<<'\n';
        //         return;
        //     }
        //     while(true){
        //         struct sockaddr_in addr;
        //         memset(&addr,0,sizeof(addr));
        //         socklen_t addrlen=sizeof(addr);
        //         int fd=accept(socketfd,(struct sockaddr*)&addr,&addrlen);
        //         sleep(1);
        //         if(fd==-1){
        //             LOG(ly::LogLevel::ERROR)<<"accept失败"<<'\n';
        //             continue;
        //         }
        //         _clientfd.push_back(fd);
        //         _pool->push(run,new std::pair<Route*,int>(this,fd));//
        //     }
        // }
    public:
        Route(uint16_t port):_port(port),_socketfd(-1){
            _socketfd=socket(AF_INET,SOCK_DGRAM,0);
            if(_socketfd==-1){
                LOG(ly::LogLevel::ERROR)<<"Error in creating socket"<<'\n';
                return;
            }
            struct sockaddr_in socket_addr;
            memset(&socket_addr,0,sizeof(socket_addr));
            socket_addr.sin_family=AF_INET;
            socket_addr.sin_addr.s_addr=INADDR_ANY;
            socket_addr.sin_port=htons(port);
            //绑定端口
            if(bind(_socketfd,(struct sockaddr*)&socket_addr,sizeof(socket_addr))==-1){
                LOG(ly::LogLevel::ERROR)<<"绑定失败"<<'\n';
                perror("bind failed");
                close(_socketfd);
                return;
            }
            _pool=ly::PthreadPool<ly::Data>::GetInstance();
            _pool->set_queue(&_queue);_pool->set_num_threads(4);
            
        }
        void Send(const std::string& message){
            if(_socketfd==-1){
                LOG(ly::LogLevel::ERROR)<<"套接字未创建";
                return;
            }
        }
        void Start(){
            if(_socketfd==-1){
                LOG(ly::LogLevel::ERROR)<<"套接字未创建";
                return;
            }
            _pool->start();//启动线程池
            run();
        }
        void getLocalAddr() {
            struct sockaddr_in addr;
            socklen_t len = sizeof(addr);
            // 获取套接字绑定的本地地址
            if (getsockname(_socketfd, (struct sockaddr*)&addr, &len) == -1) {
                perror("getsockname failed");
                return;
            }
            // 转换IP为字符串
            char ip[INET_ADDRSTRLEN];
            inet_ntop(AF_INET, &addr.sin_addr, ip, sizeof(ip));
            // 转换端口为本地字节序
            uint16_t port = ntohs(addr.sin_port);
            LOG(ly::LogLevel::INFO) << "本地绑定的IP: " << ip << ", 端口: " << port << '\n';
        }
        ~Route(){
            close(_socketfd);
        }
    private:
        int _socketfd;
        ly::PthreadPool<ly::Data>* _pool;
        ly::BlockQueue<ly::Data> _queue;
        uint16_t _port;
        std::unordered_map<std::string,struct sockaddr_in> _client_addr;
        int _pthraedid;
};